package top.wangjiu.reactive.rpc.autoconfigure.server;


import io.netty.util.internal.SocketUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.wangjiu.reactive.rpc.config.ServerConfiguration;
import top.wangjiu.reactive.rpc.registration.LocalServerRegister;
import top.wangjiu.reactive.rpc.registration.ServerRegister;
import top.wangjiu.reactive.rpc.spring.server.RpcService;

import java.util.Map;

@Configuration
@EnableConfigurationProperties(ReactiveRpcServerProperties.class)
public class ReactiveServerAutoConfiguration implements ApplicationContextAware, InitializingBean {

    private ApplicationContext context;

    @Bean
    @ConditionalOnMissingBean
    public ServerRegister serverRegister(){
        LocalServerRegister localServerRegister = new LocalServerRegister();
        return localServerRegister;
    }

    @Bean
    @ConditionalOnMissingBean
    public ServerConfiguration serverConfiguration(ServerRegister serverRegister,ReactiveRpcServerProperties reactiveRpcServerProperties){
        ServerConfiguration configuration = new ServerConfiguration();
        //todo 端口改成可配置
        configuration.setServerAddress(SocketUtils.socketAddress("localhost",reactiveRpcServerProperties.getPort()));
        configuration.setServerRegister(serverRegister);
        return configuration;
    }

    @Bean
    @ConditionalOnMissingBean
    public RpcApplicationServer rpcApplicationServer(ServerConfiguration serverConfiguration){
        return new RpcApplicationServer(serverConfiguration);
    }


    @Override
    public void afterPropertiesSet() throws Exception {

        ServerConfiguration configuration = context.getBean(ServerConfiguration.class);
        Map<String, Object> serviceInstance = context.getBeansWithAnnotation(RpcService.class);
        ServerRegister serverRegister = configuration.getServerRegister();
        serviceInstance.forEach((name,instance)->{
            RpcService serviceMeta = instance.getClass().getAnnotation(RpcService.class);
            Class service = serviceMeta.value();
            int version = serviceMeta.version();
            if(service.isInstance(instance)){
                serverRegister.registService(service,version,instance);
            }else {
                //log.warn("无效的rpcservice:{}",instance.getClass());
            }
        });
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
